package com.bootx.service.predict;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 方法四：Markov 状态转移预测
 * 思路：将红包金额离散化成状态，构建状态转移概率矩阵，基于最后一个状态预测下一个。
 */
public class MarkovPredictor {

    private int discretize(double amount) {
        return (int) (amount * 100); // 转为分
    }

    public List<Prediction> predict(List<RedPackageRound> rounds) {
        Map<Integer, Map<Integer, Map<Integer, Integer>>> transitions = new HashMap<>();

        for (int order = 1; order <= 10; order++) {
            transitions.put(order, new HashMap<>());
        }

        for (int i = 0; i < rounds.size() - 1; i++) {
            RedPackageRound r1 = rounds.get(i);
            RedPackageRound r2 = rounds.get(i + 1);

            for (int j = 0; j < r1.items.size(); j++) {
                int order = r1.items.get(j).order;
                int s1 = discretize(r1.items.get(j).amount);
                int s2 = discretize(r2.items.get(j).amount);
                transitions.get(order).computeIfAbsent(s1, k -> new HashMap<>())
                           .merge(s2, 1, Integer::sum);
            }
        }

        // 预测
        RedPackageRound last = rounds.get(rounds.size() - 1);
        List<Prediction> predictions = new ArrayList<>();
        for (RedPackageItem item : last.items) {
            int lastState = discretize(item.amount);
            int order = item.order;
            Map<Integer, Integer> nextMap = transitions.get(order).getOrDefault(lastState, Map.of());
            int nextState = nextMap.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).orElse(lastState);
            double predictedAmount = nextState / 100.0;
            int predictedTime = item.openTime; // 时间这里我们先保守预测一样
            predictions.add(new Prediction(order, predictedAmount, predictedTime));
        }

        return predictions;
    }
}
